package _11_整理题目._整理基础._集合源码;

import org.junit.Test;

public class _String_创建了几个对象 {
    // 问题： 在Java中，new String("hello")这样的创建方式，到底创建了几个String对象？
    // 如果常量池中有这个字符串（自己直接赋值，或者程序启动时别的程序创建），
    // 则只需在堆上创建一个对象；
    // 否则，先在常量池中创建一个，再在堆中创建一个，一共两个。
    /*
        对于s1，对其定义时pool中没有"abc"，String s1=new String("abc")会先后在pool中和heap中定义"abc"，所以它创建了两个对象；
        对于s2，它只在heap中定义了一个"abc"，所以它创建了一个对象；
        而对于ss1和ss2，他们定义的时候pool中已经有了"abc"，所以定义了0个对象。
     */
    @Test
    public void testNewString1() {
        String s1=new String("abc");
        String ss1="abc";
        String s2=new String("abc");
        String ss2="abc";
        
        System.out.println(s1==s2);
        System.out.println(ss1==ss2);
        System.out.println(s1==ss1);
    }
    
    // 拼接 +         的字符串 是否相等
                // 常量池指的是在编译期被确定, + 在编译之后就已经连接上字符串了，所以为 true，
                // 且只创建了一个字符串对象，没有临时的字符串
    // 拼接 + new     的字符串 是否相等
                // 
    @Test
    public void testNewString2() {
        String s0 = "hello";
        String s1 = "hello";
        String s2 = "he" + "llo";
        String s3 = "he" + new String("llo");
    
        System.out.println(s0 == s1);
        System.out.println(s0 == s2);// true
        System.out.println(s0 == s3);// false
        System.out.println();
    }
    
    /*
        String str = "abc" + new String("def"); 会创建几个对象？
        4个对象的说法：常量池中分别有“abc”和“def”，堆中对象new String(“def”)和“abcdef”
        这种说法对吗？不完全对，如果说上述代码创建了几个字符串对象，那么可以说是正确的。
        但上述的代码Java虚拟机在编译的时候同样会优化，会创建一个StringBuilder来进行字符串的拼接
        多出了一个StringBuilder对象，那就应该是5个对象。
        
        此处的 str 不会在常量池中保存一份
     */
    @Test
    public void testNewString3() {
        String s1 = "abc";
        String s2 = new String("def");
        String s3 = s1 + s2;
        String s4 = "abcdef";
        System.out.println(s3==s4); // false
        
    }
}
